package com.shanxia.codec.cmd;

import com.shanxia.codec.ProtocolDataBase;
import com.shanxia.codec.enums.BatteryTypeEnum;
import com.shanxia.codec.enums.ChargeStartFailEnum;
import com.shanxia.codec.enums.DecodeEnum;
import com.shanxia.codec.enums.SystemWarningEnum;
import lombok.Data;

import java.math.BigDecimal;
import java.util.Arrays;

import static com.shanxia.codec.CodeConstant.TEMPE_OFFSET;
import static com.shanxia.codec.CodeConstant.TENTH;
import static com.shanxia.codec.Decoder.*;

/**
 * C -> S
 * 充电桩上报充电启动完成命令
 * 充电桩上报充电启动完成命令
 */
@Data
public class Cmd110 extends ProtocolDataBase {

    public static final int MIN_SIZE = 155;

    private int v1;
    private int v2;
    private String sn;                              // 充电桩编码
    private int pileNum;                            // 充电枪号
    private ChargeStartFailEnum failReason;         // 充电失败原因
    private int reportReason;                       // 发送此报文原因
    private int v3;                                 // 预留
    private int v4;                                 // 预留
    private String commuVer;                        // BRM-BMS 通讯协议版本号
    private BatteryTypeEnum batteryType;            // BRM-电池类型
    private double ratedCapacity;                   // BRM-整车动力蓄电池系统额 定容量/Ah
    private double ratedVol;                        // BRM-整车动力蓄电池系统额 定总电压/V
    private int manufacturer;                       // BRM-电池生产厂商
    private int groupSerialNum;                     // BRM-电池组序号
    private String dateOfManufacture;               // BRM-电池组生厂日期
    private int chargingCount;                      // BRM-电池组充电次数
    private int propRightSign;                      // BRM-电池组产权标识
    private int v5;
    private String vin;                             // BRM-车辆识别码 vin
    private int softwareVer;                        // BRM-BMS 软件版本号
    private String softwareVerDate;                 // BRM-BMS 软件版本日期
    private double maxChargingVol;                  // BCP-单体动力蓄电池最高允 许充电电压
    private double maxChargingCurrent;              // BCP-最高允许充电电流
    private double maxTotalEnergy;                  // BCP-动力蓄电池标称总能量
    private double maxTotalChargingVol;             // BCP-最高允许充电总电压
    private int maxTempe;                           // BCP-最高允许温度
    private int loadStatus;                         // BCP-整车动力蓄电池荷电状态
    private double currentVol;                      // BCP-整车动力蓄电池当前电池电压
    private String serialNum;                       // 充电流水号

    public Cmd110(){
        super.setCmd(110);
    }

    public static Cmd110 decodeFromBase(ProtocolDataBase protocolDataBase) {
        Cmd110 cmd = new Cmd110();
        cmd.copyDataFrom(protocolDataBase);

        byte[] dataField = protocolDataBase.getDataField();
        //数据域长度
        if (dataField.length < MIN_SIZE) {
            cmd.setResult(DecodeEnum.InvalidData);
            return cmd;
        }
        int offset = 0;
        cmd.v1 = getUint16(dataField, offset);
        offset += 2;
        cmd.v2 = getUint16(dataField, offset);
        offset += 2;
        // 32字节序列号
        cmd.sn = byteToAscii(Arrays.copyOfRange(dataField, offset, offset + 32), true);
        offset += 32;
        // 1字节充电枪号
        cmd.pileNum = getUint8(dataField[offset++]);
        // 4字节充电失败原因
        cmd.failReason = ChargeStartFailEnum.getByCode(getInt32(dataField, 4));
        offset += 4;
        // 2字节发送此报文原因
        cmd.reportReason = getUint16(dataField, 2);
        offset += 2;
        // 2字节预留
        cmd.v3 = getUint16(dataField, 2);
        offset += 2;
        // 2字节预留
        cmd.v4 = getUint16(dataField, 2);
        offset += 2;
        // 3字节BRM-BMS 通讯协议版本号
        offset++;   // 第一字节为占位？
        int mainVer = getUint8(dataField[offset++]);
        int subVer = getUint8(dataField[offset++]);
        cmd.commuVer = mainVer + "." + subVer;
        offset += 3;
        // 1字节BRM-电池类型
        cmd.batteryType = BatteryTypeEnum.getByCode(getUint8(dataField[offset++]));
        // 4字节BRM-整车动力蓄电池系统额定容量/Ah
        cmd.ratedCapacity = new BigDecimal(getInt32(dataField, offset)).multiply(TENTH).doubleValue();
        offset += 4;
        // 4字节BRM-整车动力蓄电池系统额定总电压/V
        cmd.ratedVol = new BigDecimal(getInt32(dataField, offset)).multiply(TENTH).doubleValue();
        offset += 4;
        // 4字节BRM-电池生产厂商
        cmd.manufacturer = getInt32(dataField, offset);
        offset += 4;
        // 4字节BRM-电池组序号，预留
        cmd.groupSerialNum = getInt32(dataField, offset);
        offset += 4;
        // 2字节BRM-电池组生厂日期：年
        // 1字节BRM-电池组生厂日期：月
        // 1字节BRM-电池组生厂日期：日
        String year = String.valueOf(getUint16(dataField, offset));
        offset += 2;
        int intMonth = getUint8(dataField[offset++]);
        String month = intMonth < 10 ? "0" + intMonth : String.valueOf(intMonth);
        int intDay = getUint8(dataField[offset++]);
        String day = intDay < 10 ? "0" + intDay : String.valueOf(intDay);
        cmd.dateOfManufacture = year + "-" + month + "-" + day;
        // 4字节BRM-电池组充电次数
        cmd.chargingCount = getInt32(dataField, offset);
        offset += 4;
        // 1字节BRM-电池组产权标识
        cmd.propRightSign = getUint8(dataField[offset++]);
        // 1字节预留
        cmd.v5 = getUint8(dataField[offset++]);
        // 17字节BRM-车辆识别码 vin
        cmd.vin = byteToAscii(Arrays.copyOfRange(dataField, offset, offset + 17), true);
        offset += 17;
        // 8字节BRM-BMS 软件版本号
        // Byte1 表示版本流水号, byte2 表示日, byte3, byte4 和 byte5 表示年, byte6,7,8预留
        cmd.softwareVer = getUint8(dataField[offset++]);
        int intSoftVerDay = getUint8(dataField[offset++]);
        int intSoftVerMonth = getUint8(dataField[offset++]);
        int intSoftVerYear = getUint16(dataField, offset);
        cmd.softwareVerDate = intSoftVerYear + "-" +
                (intSoftVerMonth < 10 ? "0" + intSoftVerMonth : intSoftVerMonth) + "-" +
                (intSoftVerDay < 10 ? "0" + intSoftVerDay : intSoftVerDay);
        offset += 8;
        // 4字节BCP-单体动力蓄电池最高允许充电电压
        cmd.maxChargingVol = new BigDecimal(getInt32(dataField, offset)).multiply(TENTH).doubleValue();
        offset += 4;
        // 4字节BCP-最高允许充电电流
        cmd.maxChargingCurrent = new BigDecimal(getInt32(dataField, offset)).multiply(TENTH).doubleValue();
        offset += 4;
        // 4字节BCP-动力蓄电池标称总能量
        cmd.maxTotalEnergy = new BigDecimal(getInt32(dataField, offset)).multiply(TENTH).doubleValue();
        offset += 4;
        // 4字节BCP-最高允许充电总电压
        cmd.maxTotalChargingVol = new BigDecimal(getInt32(dataField, offset)).multiply(TENTH).doubleValue();
        offset += 4;
        // 1字节BCP-最高允许温度
        cmd.maxTempe = getUint8(dataField[offset++]) + TEMPE_OFFSET;
        // 2字节BCP-整车动力蓄电池荷电状态
        cmd.loadStatus = getUint16(dataField, offset);
        offset += 2;
        // 4字节BCP-整车动力蓄电池当前电池电压
        cmd.currentVol = new BigDecimal(getInt32(dataField, offset)).multiply(TENTH).doubleValue();
        offset += 4;
        // 32字节充电流水号
        cmd.serialNum = byteToAscii(Arrays.copyOfRange(dataField, offset, offset + 32), true);
        return cmd;
    }

    @Override
    public String toString() {

        StringBuffer buffer = new StringBuffer();
        buffer.append("#cmd110#").append("\n");
        buffer.append("v1:").append(v1).append("\n");
        buffer.append("v2:").append(v2).append("\n");
        buffer.append("充电桩编码:").append(sn).append("\n");
        buffer.append("充电枪号:").append(pileNum).append("\n");                            //
        buffer.append("充电失败原因:").append(failReason==null ? "" : failReason.descr).append("\n");         //
        buffer.append("发送此报文原因:").append(reportReason).append("\n");                       //
        buffer.append("预留v3:").append(v3).append("\n");                                 //
        buffer.append("预留v4:").append(v4).append("\n");                                 //
        buffer.append("BRM-BMS 通讯协议版本号:").append(commuVer).append("\n");                        //
        buffer.append("BRM-电池类型:").append(batteryType==null ? "" : batteryType.name).append("\n");            //
        buffer.append("BRM-整车动力蓄电池系统额 定容量/Ah:").append(ratedCapacity).append("\n");                   //
        buffer.append("BRM-整车动力蓄电池系统额 定总电压/V:").append(ratedVol).append("\n");                        //
        buffer.append("BRM-电池生产厂商:").append(manufacturer).append("\n");                       //
        buffer.append("BRM-电池组序号:").append(groupSerialNum).append("\n");                     //
        buffer.append("BRM-电池组生厂日期:").append(dateOfManufacture).append("\n");               //
        buffer.append("BRM-电池组充电次数:").append(chargingCount).append("\n");                      //
        buffer.append("BRM-电池组产权标识:").append(propRightSign).append("\n");                      //
        buffer.append("预留v5:").append(v5).append("\n");
        buffer.append("BRM-车辆识别码 vin:").append(vin).append("\n");                             //
        buffer.append("BRM-BMS 软件版本号:").append(softwareVer).append("\n");                        //
        buffer.append("BRM-BMS 软件版本日期:").append(softwareVerDate).append("\n");                 //
        buffer.append("BCP-单体动力蓄电池最高允 许充电电压:").append(maxChargingVol).append("\n");                  //
        buffer.append("BCP-最高允许充电电流:").append(maxChargingCurrent).append("\n");              //
        buffer.append("BCP-动力蓄电池标称总能量:").append(maxTotalEnergy).append("\n");                  //
        buffer.append("BCP-最高允许充电总电压:").append(maxTotalChargingVol).append("\n");             //
        buffer.append("BCP-最高允许温度:").append(maxTempe).append("\n");                           //
        buffer.append("BCP-整车动力蓄电池荷电状态:").append(loadStatus).append("\n");                         //
        buffer.append("BCP-整车动力蓄电池当前电池电压:").append(currentVol).append("\n");                      //
        buffer.append("充电流水号:").append(serialNum).append("\n");                       //
        return buffer.toString();
    }
}
